﻿using ActSupportMsgLib;
using ActUtlTypeLib;
using IcsSEMCtrl.Com.FieldBus;
using IcsSEMCtrl.Device.Observe;
using IcsSEMCtrl.Global.Com;
using IcsSEMCtrl.Global.Device;
using IcsSEMCtrl.Service.Logger;
using IcsSEMCtrl.Util;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
namespace EzControl.Driver.MelsecNet
{
    public class CMelsecNetDriver : AbstractFieldBusDriver
    {
        private const int m_iMinWorkingSetSize = 1048576;
        private const int m_iMaxWorkingSetSize = 3145728;
        private CMelsecNetMemoryCollection m_MonitorMemory = new CMelsecNetMemoryCollection();
        private ThreadPriority m_ThreadPriority = ThreadPriority.Highest;
        private System.Timers.Timer m_tmrMonitor = new System.Timers.Timer();
        private bool m_bMonitoring = false;
        private bool m_bEnableMonitoring = false;
        private short m_sMaxReadSize = 5524;
        private bool m_bScanflag;
        private int m_nMonitorInterval = 10;
        private object m_Monitor = new object();
        private short m_sChannelNo;
        private short m_sStationNo;
        private short m_sMode;
        private int m_iPath;
        public ThreadPriority ThreadPriority
        {
            get
            {
                return this.m_ThreadPriority;
            }
            set
            {
                this.m_ThreadPriority = value;
            }
        }
        public int MonitorInterval
        {
            get
            {
                return this.m_nMonitorInterval;
            }
            set
            {
                this.m_nMonitorInterval = value;
            }
        }
        public short ChannelNo
        {
            get
            {
                return this.m_sChannelNo;
            }
            set
            {
                this.m_sChannelNo = value;
            }
        }
        public short StationNo
        {
            get
            {
                return this.m_sStationNo;
            }
            set
            {
                this.m_sStationNo = value;
            }
        }
        public short Mode
        {
            get
            {
                return this.m_sMode;
            }
            set
            {
                this.m_sMode = value;
            }
        }
        public int Path
        {
            get
            {
                return this.m_iPath;
            }
        }
        public CMelsecNetDriver()
        {
            this.m_bScanflag = false;
            this.m_sChannelNo = 51;
            this.m_sStationNo = 255;
            this.m_sMode = -1;
            this.m_iPath = 0;
            CMelsecNetDriver.SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, 1048576, 3145728);
            this.m_tmrMonitor.Elapsed += new ElapsedEventHandler(this.m_tmrMonitor_Elapsed);
        }
        protected void Dispose(bool disposing)
        {
            this.StopMonitorThread();
        }
        /// <summary>
        /// PLC点位刷新
        /// </summary>
        /// <returns></returns>
        private int RefreshMonitorMemory()
        {
            int result;
            try
            {
/*                lock (this.m_Monitor)
                {*/
                    //short[] plcArrayB = null;
                    //short[] plcArrayW = null;
                    if (m_PlaybackMode)
                    {
                        return 0;
                    }
                    foreach (CMelsecNetMemory current in this.m_MonitorMemory.Values)
                    {
                        enumDeviceType deviceType = current.DeviceType;
                        if (deviceType <= enumDeviceType.SW)
                        {
                            switch (deviceType)
                            {
                                case enumDeviceType.X:
                                case enumDeviceType.Y:
                                case enumDeviceType.SB:
                                    goto IL_86;
                                case (enumDeviceType)3:
                                case (enumDeviceType)4:
                                    break;
                                default:
                                    if (deviceType == enumDeviceType.SW)
                                    {
                                        goto IL_100;
                                    }
                                    break;
                            }
                        }
                        else
                        {
                            switch (deviceType)
                            {
                                case enumDeviceType.B:
                                    goto IL_86;
                                case enumDeviceType.W:
                                    goto IL_100;
                                default:
                                    switch (deviceType)
                                    {
                                        case enumDeviceType.WW:
                                        case enumDeviceType.WR:
                                            goto IL_100;
                                    }
                                    break;
                            }
                        }
                        continue;
                    IL_86:
                        //short num = (short)current.RawMemorySize;
                        //modify by yangshl 2023/8/7
                        //plcArrayB = new short[(int)num];
                        int num2 = CMelsecNetDriver.mdReceive(this.m_iPath, this.m_sStationNo, (short)current.DeviceType, current.StartAdderess, current.RawMemorySize, out short[] plcArrayB);
                        //int num2 = (int)CMelsecNetDriver.mdReceive(this.m_iPath, this.m_sStationNo, (short)current.DeviceType, current.StartAdderess, ref num, current.RawMemory);
                        if (!this.IsSuccess(num2))
                        {
                            result = -1;
                            return result;
                        }
                        else if (plcArrayB != null)
                        {
                            for (int i = 0; i < plcArrayB.Length; i++)
                            {
                                m_MonitorMemory["B"].RawMemory[i] = plcArrayB[i];
                            }
                        }
                        continue;
                    IL_100:
                        //plcArrayW = new short[(int)this.m_sMaxReadSize];
                        int num3 = 0;
                        int num4 = 0;
                        while (current.RawMemorySize > (int)this.m_sMaxReadSize * num4)
                        {
                            if (current.RawMemorySize >= (int)this.m_sMaxReadSize * (num4 + 1))
                            {
                                num3 = (short)(this.m_sMaxReadSize * 2);
                            }
                            else
                            {
                                num3 = (short)((current.RawMemorySize - (int)this.m_sMaxReadSize * num4));
                            }
/*                            short[] plcArrayW = new short[0];
                            num2 = 0;

                            DateTime sourceDateTime = DateTime.Now;*/
                            num2 = CMelsecNetDriver.mdReceive(this.m_iPath, this.m_sStationNo, (short)current.DeviceType, (short)((int)current.StartAdderess * num4), num3, out short[] plcArrayW);
/*                            List<Task<Tuple<int, short[]>>> tasks = new List<Task<Tuple<int, short[]>>>();
                            tasks.Add(Task.Run(getData1));
                            tasks.Add(Task.Run(getData2));
                            tasks.Add(Task.Run(getData3));
                            tasks.Add(Task.Run(getData4));
                            tasks.Add(Task.Run(getData5));
                            tasks.Add(Task.Run(getData6));

                            Task<Tuple<int, short[]>[]> tasksResult = Task.WhenAll(tasks);
                            Tuple<int, short[]>[] results = tasksResult.Result;
                            foreach (Tuple<int, short[]> item in results)
                            {
                                num2 += item.Item1;
                                plcArrayW = plcArrayW.Concat(item.Item2).ToArray();
                            }*/

     /*                       DateTime destDateTime = DateTime.Now;
                            TimeSpan timeSpan = sourceDateTime - destDateTime;
                            Console.WriteLine(timeSpan.TotalMilliseconds);*/
                            if (!this.IsSuccess(num2))
                            {
                                result = -1;
                                return result;
                            }
                            else if (plcArrayW != null)
                            {
                                for (int i = 0; i < plcArrayW.Length; i++)
                                {
                                    m_MonitorMemory["W"].RawMemory[i] = plcArrayW[i];
                                }
                            }
                            num4++;
                        }
                    }



                    //2024.01.13 暂时取消（JGZ）
                    //PlayBack Log保存
                    StringBuilder backLog = new StringBuilder();
                    backLog.Append("PLC@");
                    foreach (CMelsecNetMemory current in this.m_MonitorMemory.Values)
                    {
                        byte[] byteArray = new byte[current.RawMemory.Length * 2];
                        for (int i = 0, j = 0; i < current.RawMemory.Length; i++, j += 2)
                        {
                            byteArray[j] = (byte)(current.RawMemory[i] & 0xFF);
                            byteArray[j + 1] = (byte)((current.RawMemory[i] >> 8) & 0xFF);
                        }
                        backLog.Append(Helper.ToHexStrFromByte(byteArray) + "@");
                    }
                    backLog.Append("/");
                    this.LogSaveHandler?.Invoke(backLog.ToString());
                //}
            }
            catch (Exception ex)
            {
                LogHelper.loggerError("RefreshMonitorMemory方法报错",ex);
            }
            result = 0;
            return result;
        }
        public Tuple<int,short[]> getData1()
        {
            short[] asData = new short[1382];
            int num2 = _MxDriver.ReadDeviceBlock2("W0", 1382, out asData[0]);
            return Tuple.Create(num2, asData);
        }
        public Tuple<int, short[]> getData2()
        {
            short[] asData = new short[1382];
            int num2 = _MxDriver.ReadDeviceBlock2("WE64", 1382, out asData[0]);
            return Tuple.Create(num2, asData);
        }
        public Tuple<int, short[]> getData3()
        {
            short[] asData = new short[1842];
            int num2 = _MxDriver.ReadDeviceBlock2("W1596", 1842, out asData[0]);
            return Tuple.Create(num2, asData);
        }
        public Tuple<int, short[]> getData4()
        {
            short[] asData = new short[1000];
            int num2 = _MxDriver.ReadDeviceBlock2("WBB9", 1000, out asData[0]);
            return Tuple.Create(num2, asData);
        }
        public Tuple<int, short[]> getData5()
        {
            short[] asData = new short[1000];
            int num2 = _MxDriver.ReadDeviceBlock2("WFA1", 1000, out asData[0]);
            return Tuple.Create(num2, asData);
        }
        public Tuple<int, short[]> getData6()
        {
            short[] asData = new short[1000];
            int num2 = _MxDriver.ReadDeviceBlock2("W1389", 526, out asData[0]);
            return Tuple.Create(num2, asData);
        }
        private bool IsSuccess(int iRet)
        {
            bool flag = iRet == 0 || iRet == 66 || iRet == -28150;
            if (!flag)
            {
                if (iRet != -1)
                {
                    base.RaiseErrorOccurred(iRet);
                }
                this.Close();
                base.ActiveOpen();
            }
            return flag;
        }
        private void InitMonitorThread()
        {
            this.m_tmrMonitor.Interval = (double)this.m_nMonitorInterval;
            this.m_bScanflag = true;
            this.m_tmrMonitor.Start(); //Add By TKT
        }
        /// <summary>
        /// PLC点位监控，time线程间隔100ms刷新
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void m_tmrMonitor_Elapsed(object sender, ElapsedEventArgs e)
        {
            this.m_tmrMonitor.Stop();
            this.m_bScanflag = false;
            if (this.RefreshMonitorMemory() == 0)
            {
                this.m_bScanflag = true;
            }
            else
            {
                this.m_bScanflag = false;
            }
            this.NewScanObservable();
            this.m_tmrMonitor.Start();

        }
        public void NewScanObservable()
        {
            if (this.registeredObservableList != null && this.registeredObservableList.Count != 0)
            {
                lock (this.registeredObservableList)
                {
                    foreach (Observable current in this.registeredObservableList.Values)
                    {
                        if (current.IsMonitoring && current.ReadValueSync(false) > 0)
                        {
                        }
                    }
                }
            }
        }
        private void StopMonitorThread()
        {
            try
            {
                this.m_bScanflag = false;
            }
            catch (Exception ex)
            {
                LogHelper.loggerError("停止监控线程", ex);
                Console.WriteLine(ex.ToString());
            }
        }
        private void StartMonitor()
        {
            this.m_bScanflag = true;
        }
        private void StopMonitor()
        {
            this.m_bScanflag = false;
        }
        protected override void ChangeConnectionState(FBConnectionState connectionState)
        {
            base.ChangeConnectionState(connectionState);
            switch (connectionState.Value())
            {
                case 2:
                    this.StopMonitor();
                    break;
                case 3:
                    this.StartMonitor();
                    break;
            }
        }
        //[DllImport("kernel32.dll")]
        //private static extern bool SetProcessWorkingSetSize(IntPtr hProcess, int iMinimumWorkingSetSize, int iMaximumWorkingSetSize);
        //[DllImport("mdfunc32.dll")]
        //private static extern short mdOpen(short sChan, short sMode, ref int iPath);
        //[DllImport("mdfunc32.dll")]
        //private static extern short mdClose(int iPath);
        //[DllImport("mdfunc32.dll")]
        //private static extern short mdDevSet(int iPath, short sStNo, short sDevTyp, short sDevNo);
        //[DllImport("mdfunc32.dll")]
        //private static extern short mdDevRst(int iPath, short sStNo, short sDevtyp, short sDevNo);
        //[DllImport("mdfunc32.dll")]
        //private static extern short mdSend(int iPath, short sStNo, short sDevTyp, short sDevNo, ref short sSize, [In] short[] asData);
        //[DllImport("mdfunc32.dll")]
        //private static extern short mdReceive(int iPath, short sStNo, short sDevTyp, short sDevNo, ref short sSize, [Out] short[] asData);
        //[DllImport("mdfunc32.dll")]
        //private static extern int mdReceiveEx(int iPath, int iNetNo, int iStNo, int iDevTyp, int iDevNo, ref int iSize, [Out] short[] asData);

        private static readonly ActUtlTypeClass _MxDriver = new ActUtlTypeClass();
        private static readonly ActSupportMsgClass _MxDriverMessage = new ActSupportMsgClass();

        private static bool SetProcessWorkingSetSize(IntPtr hProcess, int iMinimumWorkingSetSize, int iMaximumWorkingSetSize)
        {
            return true;
        }

        private static short mdOpen(short sChan, short sMode, ref int iPath)
        {
            short nRetCode = -1;
            _MxDriver.ActLogicalStationNumber = 1;
            _MxDriver.ActPassword = "";
            nRetCode = (short)_MxDriver.Open();
            return nRetCode;
        }

        private static short mdClose(int iPath)
        {
            short nRetCode = (short)_MxDriver.Close();
            return nRetCode;
        }

        private static short mdDevSet(int iPath, short sStNo, short sDevTyp, short sDevNo)
        {
            string strDevType = "";
            string strDevNo = "";
            switch (sDevTyp)
            {
                case 23:
                    strDevType = "B";
                    strDevNo = string.Format("{0:X}", sDevNo);
                    break;
                case 24:
                    strDevType = "W";
                    strDevNo = string.Format("{0:X}", sDevNo);
                    break;
                default:
                    break;
            }
            string szDevice = strDevType + strDevNo;
            short[] asData = new short[1] { 1 };
            short nRetCode = (short)_MxDriver.SetDevice(szDevice, 1);// WriteDeviceBlock2(szDevice, 1, ref asData[0]);
            return nRetCode;
        }

        private static short mdDevRst(int iPath, short sStNo, short sDevTyp, short sDevNo)
        {
            string strDevType = "";
            string strDevNo = "";
            switch (sDevTyp)
            {
                case 23:
                    strDevType = "B";
                    strDevNo = string.Format("{0:X}", sDevNo);
                    break;
                case 24:
                    strDevType = "W";
                    strDevNo = string.Format("{0:X}", sDevNo);
                    break;
                default:
                    break;
            }
            string szDevice = strDevType + strDevNo;
            short[] asData = new short[1] { 0 };
            short nRetCode = (short)_MxDriver.SetDevice(szDevice, 0);//WriteDeviceBlock2(szDevice, 1, ref asData[0]);
            return nRetCode;
        }

        static object rLocker = new object();
        static object wLocker = new object();

        private static int mdSend(int iPath, short sStNo, short sDevTyp, short sDevNo, int sSize, short[] asData)
        {
            lock (wLocker)
            {
                string strDevType = "";
                string strDevNo = "";
                switch (sDevTyp)
                {
                    case 23:
                        strDevType = "B";
                        strDevNo = string.Format("{0:X}", sDevNo);
                        break;
                    case 24:
                        strDevType = "W";
                        strDevNo = string.Format("{0:X}", sDevNo);
                        break;
                    default:
                        break;
                }
                string szDevice = strDevType + strDevNo;
                int nRetCode = _MxDriver.WriteDeviceBlock2(szDevice, sSize, ref asData[0]);
                return nRetCode;
            }
        }

        private static int mdReceive(int iPath, short sStNo, short sDevTyp, short sDevNo, int sSize, out short[] asData)
        {
            lock (rLocker)
            {
                asData = new short[sSize];
                string strDevType = "";
                string strDevNo = "";
                switch (sDevTyp)
                {
                    case 23:
                        strDevType = "B";
                        strDevNo = string.Format("{0:X}", sDevNo);
                        break;
                    case 24:
                        strDevType = "W";
                        strDevNo = string.Format("{0:X}", sDevNo);
                        break;
                    default:
                        break;
                }
                string szDevice = strDevType + strDevNo;
                int nRetCode = _MxDriver.ReadDeviceBlock2(szDevice, sSize, out asData[0]);
                //short nRetCode = (short)_MxDriver.ReadDeviceRandom2(szDevice, nSize, out asData[0]);
                return nRetCode;
            }
        }

        private static int mdReceiveEx(int iPath, int iNetNo, int iStNo, int iDevTyp, int iDevNo, ref int iSize, [Out] short[] asData)
        {
            return 0;
        }



        public bool SetBit(short sAddress, enumDeviceType DeviceType)
        {
            return this.SetBit(sAddress, this.m_sStationNo, DeviceType);
        }
        public bool SetBit(short sAddress, short sStationNo, enumDeviceType DeviceType)
        {
            bool result;
            if (!base.Enabled)
            {
                result = false;
            }
            else
            {
                int iRet = (int)CMelsecNetDriver.mdDevSet(this.m_iPath, sStationNo, (short)DeviceType, sAddress);
                result = this.IsSuccess(iRet);
            }
            return result;
        }
        public bool ResetBit(short sAddress, enumDeviceType DeviceType)
        {
            return this.ResetBit(sAddress, this.m_sStationNo, DeviceType);
        }
        public bool ResetBit(short sAddress, short sStationNo, enumDeviceType DeviceType)
        {
            bool result;
            if (!base.Enabled)
            {
                result = false;
            }
            else
            {
                int iRet = (int)CMelsecNetDriver.mdDevRst(this.m_iPath, sStationNo, (short)DeviceType, sAddress);
                result = this.IsSuccess(iRet);
            }
            return result;
        }
        public bool ReadBit(short sAddress, int nIndex, enumDeviceType DeviceType, out bool bValue)
        {
            return this.ReadBit(sAddress, nIndex, this.m_sStationNo, DeviceType, out bValue);
        }
        public bool ReadBit(short sAddress, int nIndex, short sStationNo, enumDeviceType DeviceType, out bool bValue)
        {
            bValue = false;
            bool result;
            if (!base.Enabled)
            {
                result = false;
            }
            else
            {
                bool flag = false;
                //short[] array = new short[1];
                //short num = 2;
                if (DeviceType <= enumDeviceType.SW)
                {
                    switch (DeviceType)
                    {
                        case enumDeviceType.X:
                        case enumDeviceType.Y:
                        case enumDeviceType.SB:
                            break;
                        case (enumDeviceType)3:
                        case (enumDeviceType)4:
                            goto IL_11C;
                        default:
                            if (DeviceType != enumDeviceType.SW)
                            {
                                goto IL_11C;
                            }
                            goto IL_D6;
                    }
                }
                else
                {
                    switch (DeviceType)
                    {
                        case enumDeviceType.B:
                            break;
                        case enumDeviceType.W:
                            goto IL_D6;
                        default:
                            switch (DeviceType)
                            {
                                case enumDeviceType.WW:
                                case enumDeviceType.WR:
                                    goto IL_D6;
                                default:
                                    goto IL_11C;
                            }
                            break;
                    }
                }
                short num2 = (short)(sAddress / 16 * 16);
                int iRet = (int)CMelsecNetDriver.mdReceive(this.m_iPath, sStationNo, (short)DeviceType, num2, 1,  out short[] array);
                if (!this.IsSuccess(iRet))
                {
                    bValue = false;
                    flag = false;
                }
                else
                {
                    bValue = (((int)array[0] & 1 << (int)(sAddress - num2)) != 0);
                    flag = true;
                }
                goto IL_11C;
            IL_D6:
                iRet = (int)CMelsecNetDriver.mdReceive(this.m_iPath, sStationNo, (short)DeviceType, sAddress, 1, out short[] array02);
                if (!this.IsSuccess(iRet))
                {
                    bValue = false;
                    flag = false;
                }
                else
                {
                    bValue = (((int)array02[0] & 1 << nIndex) != 0);
                    flag = true;
                }
            IL_11C:
                result = flag;
            }
            return result;
        }
        public bool WriteBit(short sAddress, int nIndex, enumDeviceType DeviceType, bool bValue)
        {
            return this.WriteBit(sAddress, nIndex, this.m_sStationNo, DeviceType, bValue);
        }
        public bool WriteBit(short sAddress, int nIndex, short sStationNo, enumDeviceType DeviceType, bool bValue)
        {
            bool result;
            if (!base.Enabled)
            {
                result = false;
            }
            else
            {
                int iRet = -1;
                if (DeviceType <= enumDeviceType.SW)
                {
                    switch (DeviceType)
                    {
                        case enumDeviceType.X:
                        case enumDeviceType.Y:
                        case enumDeviceType.SB:
                            break;
                        case (enumDeviceType)3:
                        case (enumDeviceType)4:
                            goto IL_116;
                        default:
                            if (DeviceType != enumDeviceType.SW)
                            {
                                goto IL_116;
                            }
                            goto IL_A4;
                    }
                }
                else
                {
                    switch (DeviceType)
                    {
                        case enumDeviceType.B:
                            break;
                        case enumDeviceType.W:
                            goto IL_A4;
                        default:
                            switch (DeviceType)
                            {
                                case enumDeviceType.WW:
                                case enumDeviceType.WR:
                                    goto IL_A4;
                                default:
                                    goto IL_116;
                            }
                            break;
                    }
                }
                if (bValue)
                {
                    iRet = (int)CMelsecNetDriver.mdDevSet(this.m_iPath, sStationNo, (short)DeviceType, sAddress);
                }
                else
                {
                    iRet = (int)CMelsecNetDriver.mdDevRst(this.m_iPath, sStationNo, (short)DeviceType, sAddress);
                }
                goto IL_116;
            IL_A4:
                //short[] array = new short[1];
                //short num = 2;
                iRet = CMelsecNetDriver.mdReceive(this.m_iPath, sStationNo, (short)DeviceType, sAddress, 1, out short[] array);
                if (this.IsSuccess(iRet))
                {
                    if (bValue)
                    {
                        array[0] = (short)((int)((ushort)array[0]) | 1 << nIndex);
                    }
                    else
                    {
                        array[0] = (short)((int)array[0] & ~(1 << nIndex));
                    }
                    iRet = CMelsecNetDriver.mdSend(this.m_iPath, sStationNo, (short)DeviceType, sAddress, 1, array);
                }
            IL_116:
                result = this.IsSuccess(iRet);
            }
            return result;
        }
        public bool ReadWord(short sAddress, enumDeviceType DeviceType, out short sValue)
        {
            return this.ReadWord(sAddress, this.m_sStationNo, DeviceType, out sValue);
        }
        public bool ReadWord(short sAddress, short sStationNo, enumDeviceType DeviceType, out short sValue)
        {
            sValue = 0;
            bool result;
            if (!base.Enabled)
            {
                result = false;
            }
            else
            {
                //short[] asData = new short[1];
                //short num = 2;
                int iRet = (int)CMelsecNetDriver.mdReceive(this.m_iPath, sStationNo, (short)DeviceType, sAddress, 1,out  short[] asData);
                result = this.IsSuccess(iRet);
            }
            return result;
        }
        public bool ReadWord(short sAddress, enumDeviceType DeviceType, short sSize, out short[] asValue)
        {
            return this.ReadWord(sAddress, this.m_sStationNo, DeviceType, sSize, out asValue);
        }
        public bool ReadWord(short sAddress, short sStationNo, enumDeviceType DeviceType, short sSize, out short[] asValue)
        {
            asValue = new short[(int)sSize];
            bool result;
            if (!base.Enabled)
            {
                result = false;
            }
            else
            {
                int num = sSize * 2;
                int iRet = CMelsecNetDriver.mdReceive(this.m_iPath, sStationNo, (short)DeviceType, sAddress, num, out short[] ReadBuffer);
                asValue = ReadBuffer;
                result = this.IsSuccess(iRet);
            }
            return result;
        }
        public bool ReadWord(short sAddress, enumDeviceType DeviceType, int nLength, out short sValue)
        {
            return this.ReadWord(sAddress, this.m_sStationNo, DeviceType, nLength, out sValue);
        }
        public bool ReadWord(short sAddress, short sStationNo, enumDeviceType DeviceType, int nLength, out short sValue)
        {
            sValue = 0;
            bool result;
            if (!base.Enabled)
            {
                result = false;
            }
            else
            {
                bool flag = false;
                //short[] array = new short[1];
                //short num = 2;
                if (DeviceType <= enumDeviceType.SW)
                {
                    switch (DeviceType)
                    {
                        case enumDeviceType.X:
                        case enumDeviceType.Y:
                        case enumDeviceType.SB:
                            break;
                        case (enumDeviceType)3:
                        case (enumDeviceType)4:
                            goto IL_13C;
                        default:
                            if (DeviceType != enumDeviceType.SW)
                            {
                                goto IL_13C;
                            }
                            goto IL_104;
                    }
                }
                else
                {
                    switch (DeviceType)
                    {
                        case enumDeviceType.B:
                            break;
                        case enumDeviceType.W:
                            goto IL_104;
                        default:
                            switch (DeviceType)
                            {
                                case enumDeviceType.WW:
                                case enumDeviceType.WR:
                                    goto IL_104;
                                default:
                                    goto IL_13C;
                            }
                            break;
                    }
                }
                short num2 = (short)(sAddress / 16 * 16);
                int iRet = CMelsecNetDriver.mdReceive(this.m_iPath, sStationNo, (short)DeviceType, num2, 1, out short[] array);
                if (!this.IsSuccess(iRet))
                {
                    sValue = 0;
                    flag = false;
                }
                else
                {
                    int num3 = 0;
                    for (int i = 0; i < nLength; i++)
                    {
                        num3 |= 1 << i;
                    }
                    int num4 = (int)array[0] & num3 << (int)(sAddress - num2);
                    sValue = (short)(num4 >> (int)(sAddress - num2));
                    flag = true;
                }
                goto IL_13C;
            IL_104:
                iRet = CMelsecNetDriver.mdReceive(this.m_iPath, sStationNo, (short)DeviceType, sAddress, 1, out short[] array02);
                if (!this.IsSuccess(iRet))
                {
                    sValue = 0;
                    flag = false;
                }
                else
                {
                    sValue = array02[0];
                    flag = true;
                }
            IL_13C:
                result = flag;
            }
            return result;
        }
        public bool ReadWord(short sAddress, enumDeviceType DeviceType, int nIndex, int nLength, out short sValue)
        {
            return this.ReadWord(sAddress, this.m_sStationNo, DeviceType, nIndex, nLength, out sValue);
        }
        public bool ReadWord(short sAddress, short sStationNo, enumDeviceType DeviceType, int nIndex, int nLength, out short sValue)
        {
            sValue = 0;
            bool result;
            if (!base.Enabled)
            {
                result = false;
            }
            else
            {
                bool flag = false;
                //short[] array = new short[1];
                //short num = 2;
                if (DeviceType <= enumDeviceType.SW)
                {
                    switch (DeviceType)
                    {
                        case enumDeviceType.X:
                        case enumDeviceType.Y:
                        case enumDeviceType.SB:
                            break;
                        case (enumDeviceType)3:
                        case (enumDeviceType)4:
                            goto IL_178;
                        default:
                            if (DeviceType != enumDeviceType.SW)
                            {
                                goto IL_178;
                            }
                            goto IL_104;
                    }
                }
                else
                {
                    switch (DeviceType)
                    {
                        case enumDeviceType.B:
                            break;
                        case enumDeviceType.W:
                            goto IL_104;
                        default:
                            switch (DeviceType)
                            {
                                case enumDeviceType.WW:
                                case enumDeviceType.WR:
                                    goto IL_104;
                                default:
                                    goto IL_178;
                            }
                            break;
                    }
                }
                short num2 = (short)(sAddress / 16 * 16);
                int iRet = CMelsecNetDriver.mdReceive(this.m_iPath, sStationNo, (short)DeviceType, num2, 1, out short[] array);
                if (!this.IsSuccess(iRet))
                {
                    sValue = 0;
                    flag = false;
                }
                else
                {
                    int num3 = 0;
                    for (int i = 0; i < nLength; i++)
                    {
                        num3 |= 1 << i;
                    }
                    int num4 = (int)array[0] & num3 << (int)(sAddress - num2);
                    sValue = (short)(num4 >> (int)(sAddress - num2));
                    flag = true;
                }
                goto IL_178;
            IL_104:
                iRet = CMelsecNetDriver.mdReceive(this.m_iPath, sStationNo, (short)DeviceType, sAddress, 1, out short[] array02);
                if (!this.IsSuccess(iRet))
                {
                    sValue = 0;
                    flag = false;
                }
                else
                {
                    int num3 = 0;
                    for (int i = 0; i < nLength; i++)
                    {
                        num3 |= 1 << i;
                    }
                    int num4 = (int)array02[0] & num3 << nIndex;
                    sValue = (short)(num4 >> nIndex);
                    flag = true;
                }
            IL_178:
                result = flag;
            }
            return result;
        }
        public bool WriteWord(short sAddress, enumDeviceType DeviceType, short sData)
        {
            return this.WriteWord(sAddress, this.m_sStationNo, DeviceType, sData);
        }
        public bool WriteWord(short sAddress, short sStationNo, enumDeviceType DeviceType, short sData)
        {
            bool result;
            if (!base.Enabled)
            {
                result = false;
            }
            else
            {
                short[] asData = new short[]
				{
					sData
				};
                int num = 2;
                int iRet = CMelsecNetDriver.mdSend(this.m_iPath, sStationNo, (short)DeviceType, sAddress, num, asData);
                result = this.IsSuccess(iRet);
            }
            return result;
        }
        public bool WriteWord(short sAddress, int nLength, enumDeviceType DeviceType, short sData)
        {
            return this.WriteWord(sAddress, nLength, this.m_sStationNo, DeviceType, sData);
        }
        public bool WriteWord(short sAddress, int nLength, short sStationNo, enumDeviceType DeviceType, short sData)
        {
            bool result;
            if (!base.Enabled)
            {
                result = false;
            }
            else
            {
                //short num = 2;
                int iRet = 0;
                if (DeviceType <= enumDeviceType.SW)
                {
                    switch (DeviceType)
                    {
                        case enumDeviceType.X:
                        case enumDeviceType.Y:
                        case enumDeviceType.SB:
                            break;
                        case (enumDeviceType)3:
                        case (enumDeviceType)4:
                            goto IL_149;
                        default:
                            if (DeviceType != enumDeviceType.SW)
                            {
                                goto IL_149;
                            }
                            goto IL_125;
                    }
                }
                else
                {
                    switch (DeviceType)
                    {
                        case enumDeviceType.B:
                            break;
                        case enumDeviceType.W:
                            goto IL_125;
                        default:
                            switch (DeviceType)
                            {
                                case enumDeviceType.WW:
                                case enumDeviceType.WR:
                                    goto IL_125;
                                default:
                                    goto IL_149;
                            }
                            break;
                    }
                }
    //            short[] array = new short[]
				//{
				//	0
				//};
                short num2 = (short)(sAddress / 16 * 16);
                iRet = CMelsecNetDriver.mdReceive(this.m_iPath, this.m_sStationNo, (short)DeviceType, num2, 1, out short[] array);
                if (this.IsSuccess(iRet))
                {
                    int num3 = 0;
                    for (int i = 0; i < nLength; i++)
                    {
                        num3 |= 1 << i;
                    }
                    num3 <<= (int)(sAddress - num2);
                    int num4 = (int)sData << (int)(sAddress - num2);
                    int num5 = (int)array[0] & ~num3;
                    num5 |= (num4 & num3);
                    array[0] = (short)num5;
                    iRet = CMelsecNetDriver.mdSend(this.m_iPath, sStationNo, (short)DeviceType, num2, 1, array);
                }
                goto IL_149;
            IL_125:
                array = new short[]
				{
					sData
				};
                iRet = (int)CMelsecNetDriver.mdSend(this.m_iPath, sStationNo, (short)DeviceType, sAddress, 1, array);
            IL_149:
                result = this.IsSuccess(iRet);
            }
            return result;
        }
        public bool WriteWord(short sAddress, int nIndex, int nLength, enumDeviceType DeviceType, short sData)
        {
            return this.WriteWord(sAddress, nIndex, nLength, this.m_sStationNo, DeviceType, sData);
        }
        public bool WriteWord(short sAddress, int nIndex, int nLength, short sStationNo, enumDeviceType DeviceType, short sData)
        {
            bool result;
            if (!base.Enabled)
            {
                result = false;
            }
            else
            {
                //short num = 2;
                int iRet = 0;
                if (DeviceType <= enumDeviceType.SW)
                {
                    switch (DeviceType)
                    {
                        case enumDeviceType.X:
                        case enumDeviceType.Y:
                        case enumDeviceType.SB:
                            break;
                        case (enumDeviceType)3:
                        case (enumDeviceType)4:
                            goto IL_1CC;
                        default:
                            if (DeviceType != enumDeviceType.SW)
                            {
                                goto IL_1CC;
                            }
                            goto IL_129;
                    }
                }
                else
                {
                    switch (DeviceType)
                    {
                        case enumDeviceType.B:
                            break;
                        case enumDeviceType.W:
                            goto IL_129;
                        default:
                            switch (DeviceType)
                            {
                                case enumDeviceType.WW:
                                case enumDeviceType.WR:
                                    goto IL_129;
                                default:
                                    goto IL_1CC;
                            }
                            break;
                    }
                }
                short[] array = new short[]
				{
					0
				};
                short num2 = (short)(sAddress / 16 * 16);
                iRet = CMelsecNetDriver.mdReceive(this.m_iPath, this.m_sStationNo, (short)DeviceType, num2, 1, out short[] array02);
                if (this.IsSuccess(iRet))
                {
                    int num3 = 0;
                    for (int i = 0; i < nLength; i++)
                    {
                        num3 |= 1 << i;
                    }
                    num3 <<= (int)(sAddress - num2);
                    int num4 = (int)sData << (int)(sAddress - num2);
                    int num5 = (int)array02[0] & ~num3;
                    num5 |= (num4 & num3);
                    array02[0] = (short)num5;
                    iRet = CMelsecNetDriver.mdSend(this.m_iPath, sStationNo, (short)DeviceType, num2, 1, array02);
                }
                goto IL_1CC;
            IL_129:
                array = new short[]
				{
					sData
				};
                iRet = CMelsecNetDriver.mdReceive(this.m_iPath, this.m_sStationNo, (short)DeviceType, sAddress, 1, out short[] array03);
                if (this.IsSuccess(iRet))
                {
                    int num3 = 0;
                    for (int i = 0; i < nLength; i++)
                    {
                        num3 |= 1 << i;
                    }
                    num3 <<= nIndex;
                    int num4 = (int)sData << nIndex;
                    int num5 = (int)array03[0] & ~num3;
                    num5 |= (num4 & num3);
                    array03[0] = (short)num5;
                    iRet = (int)CMelsecNetDriver.mdSend(this.m_iPath, sStationNo, (short)DeviceType, sAddress, 1, array03);
                }
            IL_1CC:
                result = this.IsSuccess(iRet);
            }
            return result;
        }
        public bool WriteWordA(short sAddress, enumDeviceType DeviceType, short sLength, string strData)
        {
            return this.WriteWordA(sAddress, this.m_sStationNo, DeviceType, sLength, strData);
        }
        public bool WriteWordA(short sAddress, short sStationNo, enumDeviceType DeviceType, short sLength, string strData)
        {
            bool result;
            if (!base.Enabled)
            {
                result = false;
            }
            else
            {
                short num = sLength;
                if (strData.Length > (int)(sLength * 2))
                {
                    strData = strData.Substring(0, (int)(sLength * 2));
                }
                strData = strData.PadRight((int)(num * 2), ' ');
                short[] array = new short[(int)num];
                for (int i = 0; i < (int)num; i++)
                {
                    array[i] = 0;
                    array[i] = Convert.ToInt16(strData[i * 2]);
                    array[i] = Convert.ToInt16((int)((ushort)array[i]) | (int)Convert.ToInt16(strData[i * 2 + 1]) << 8);
                }
                if (base.Connected)
                {
                }
                int iRet;
                if (DeviceType == enumDeviceType.R)
                {
                    iRet = CMelsecNetDriver.mdSend(this.m_iPath, sStationNo, (short)DeviceType, sAddress, num, array);
                }
                else
                {
                    iRet = CMelsecNetDriver.mdSend(this.m_iPath, sStationNo, (short)DeviceType, sAddress, num, array);
                }
                result = this.IsSuccess(iRet);
            }
            return result;
        }
        public bool ReadWordA(short sAddress, enumDeviceType DeviceType, short sLength, out string strValue)
        {
            return this.ReadWordA(sAddress, this.m_sStationNo, DeviceType, sLength, out strValue);
        }
        public bool ReadWordA(short sAddress, short sStationNo, enumDeviceType DeviceType, short sLength, out string strValue)
        {
            strValue = "";
            bool result;
            if (!base.Enabled)
            {
                result = false;
            }
            else
            {
                int num = sLength;
                //short[] array = new short[(int)num];
                num *= 2;
                int iRet = (int)CMelsecNetDriver.mdReceive(this.m_iPath, sStationNo, (short)DeviceType, sAddress, num, out short[] array);
                if (!this.IsSuccess(iRet))
                {
                    strValue = "";
                    result = false;
                }
                else
                {
                    char[] rByteDatas = new char[array.Length * 2];
                    for (int i = 0; i < array.Length; i++)
                    {
                        rByteDatas[2 * i] = (char)(array[i] & 0xFF);
                        rByteDatas[2 * i + 1] = (char)((array[i] >> 8) & 0xFF);
                    }
                    System.Text.StringBuilder strBuilder = new System.Text.StringBuilder();
                    foreach (char b in rByteDatas)
                    {
                        if (b != 0)
                            strBuilder.Append(b);
                    }
                    strValue = strBuilder.ToString();
                    strValue = strValue.Trim();
                    //strValue = System.Text.Encoding.ASCII.GetString(rByteDatas);

                    //    for (int i = 0; i < (int)(num / 2); i++)
                    //    {
                    //        strValue += Convert.ToChar((int)(array[i] & 255));
                    //        strValue += Convert.ToChar(array[i] >> 8 & 255);
                    //    }
                    bool flag = true;
                    //strValue = strValue.Trim();
                    //if (strValue.Length > (int)(sLength * 2))
                    //{
                    //    strValue = strValue.Substring(0, (int)(sLength * 2));
                    //}
                    //strValue = strValue.Trim(" \0".ToCharArray());
                    result = flag;
                }
            }
            return result;
        }
        protected override void InitConnectionString(string sCnnString)
        {
            this.connectionInfo = new CMelsecNetConnection();
            this.connectionInfo.Parse(sCnnString);
            this.UpdateConnectionInfo();
        }
        private void UpdateConnectionInfo()
        {
            //连接信息字典中是否包含此字段，若包含则返回字典中字段对象的数据，否则返回默认值51
            this.m_sChannelNo = (short)this.connectionInfo["CHANNEL_NO", 51];
            this.m_sMode = (short)this.connectionInfo["MODE", -1];
            this.m_sStationNo = (short)this.connectionInfo["STATION_NO", 255];
            this.m_nMonitorInterval = this.connectionInfo["MONITOR_INTERVAL", 100];
            this.m_MonitorMemory.Clear();
            string[] names = Enum.GetNames(typeof(enumDeviceType));
            for (int i = 0; i < names.Length; i++)
            {
                if (this.connectionInfo.ContainsKey(string.Format("{0}_START_ADDR", names[i])) && this.connectionInfo.ContainsKey(string.Format("{0}_END_ADDR", names[i])))
                {
                    //PLC地址范围字典集合m_MonitorMemory，添加数据
                    this.m_MonitorMemory.Add(names[i], new CMelsecNetMemory((enumDeviceType)Enum.Parse(typeof(enumDeviceType), names[i]), (short)this.connectionInfo[string.Format("{0}_START_ADDR", names[i]), 0], (short)this.connectionInfo[string.Format("{0}_END_ADDR", names[i]), 0]));
                }
            }
        }
        private bool CheckConnection()
        {
            //short sSize = 2;
            //short[] asData = new short[1];
            int nRetCode = CMelsecNetDriver.mdReceive(this.m_iPath, this.m_sStationNo, 23, 0, 1, out short[] asData);
            return nRetCode == 0 || nRetCode == 66 || nRetCode == -28150;
        }
        /// <summary>
        /// 使用MX协议，打开PLC连接
        /// </summary>
        /// <returns></returns>
        public override int Open()
        {
            int result;
            try
            {
                if (base.Connected)
                {
                    this.Close();
                }
                if (this.connectionInfo != null)
                {
                    this.UpdateConnectionInfo();
                }
                if (CMelsecNetDriver.mdOpen(this.m_sChannelNo, this.m_sMode, ref this.m_iPath) == 0 && this.CheckConnection())
                {
                    base.ConnectionState = FBConnectionState.CONNECTED;
                    //PLC点位刷新监控
                    this.InitMonitorThread();
                    result = 0;
                }
                else
                {
                    CMelsecNetDriver.mdClose(this.m_iPath);
                    result = -1;
                }
            }
            catch (Exception ex)
            {
                LogHelper.loggerError("ERR MSG:" + ex.Message, ex);
                Console.WriteLine("ERR MSG:" + ex.Message);
                result = -1;
            }
            return result;
        }
        public override int Open(string strConnectionString)
        {
            this.connectionInfo = new CMelsecNetConnection();
            this.connectionInfo.Parse(strConnectionString);
            this.UpdateConnectionInfo();
            short nRetCode = CMelsecNetDriver.mdOpen(this.m_sChannelNo, this.m_sMode, ref this.m_iPath);
            int result;
            if (nRetCode == 0)
            {
                if (this.CheckConnection())
                {
                    base.ConnectionState = FBConnectionState.CONNECTED;
                    this.InitMonitorThread();
                    result = 0;
                }
                else
                {
                    result = -1;
                }
            }
            else
            {
                CMelsecNetDriver.mdClose(this.m_iPath);
                result = (int)nRetCode;
            }
            return result;
        }
        public override int Close()
        {
            base.ConnectionState = FBConnectionState.DISCONNECTED;
            CMelsecNetDriver.mdClose(this.m_iPath);
            return 0;
        }
        /// <summary>
        /// 不同数据类型的值写入PLC
        /// </summary>
        /// <param name="observable"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public override int Write(Observable observable, object value)
        {
            int result;
            if (!base.Connected)
            {
                result = 1;
            }
            else
            {
                if (observable.ConnectionInfoString == string.Empty)
                {
                    result = 1;
                }
                else
                {
                    if (observable.AccessType != AccessType.OUT && observable.AccessType != AccessType.IN_OUT)
                    {
                        result = 1;
                    }
                    else
                    {
                        switch (observable.DataType.Value())
                        {
                            case 0:
                                {
                                    short num = Convert.ToInt16(observable.ConnectionInfo["STATION_NO", -1]);
                                    if (num >= 0)
                                    {
                                        this.WriteBit((short)observable.ConnectionInfo["ADDRESS_NO", 0, 16], observable.ConnectionInfo["BIT_INDEX", 0], num, (enumDeviceType)Enum.Parse(typeof(enumDeviceType), observable.ConnectionInfo["DEVICE_TYPE", "B"]), (bool)value);
                                    }
                                    else
                                    {
                                        this.WriteBit((short)observable.ConnectionInfo["ADDRESS_NO", 0, 16], observable.ConnectionInfo["BIT_INDEX", 0], (enumDeviceType)Enum.Parse(typeof(enumDeviceType), observable.ConnectionInfo["DEVICE_TYPE", "B"]), (bool)value);
                                    }
                                    break;
                                }
                            case 2:
                                {
                                    short num = Convert.ToInt16(observable.ConnectionInfo["STATION_NO", -1]);
                                    if (num >= 0)
                                    {
                                        if (observable.ConnectionInfo.ContainsKey("BIT_INDEX"))
                                        {
                                            this.WriteWord((short)observable.ConnectionInfo["ADDRESS_NO", 0, 16], observable.ConnectionInfo["BIT_INDEX", 0], observable.ConnectionInfo["BIT_LENGTH", 0], num, (enumDeviceType)Enum.Parse(typeof(enumDeviceType), observable.ConnectionInfo["DEVICE_TYPE", "W"]), (short)value);
                                        }
                                        else
                                        {
                                            this.WriteWord((short)observable.ConnectionInfo["ADDRESS_NO", 0, 16], observable.ConnectionInfo["BIT_LENGTH", 0], num, (enumDeviceType)Enum.Parse(typeof(enumDeviceType), observable.ConnectionInfo["DEVICE_TYPE", "W"]), (short)value);
                                        }
                                    }
                                    else
                                    {
                                        if (observable.ConnectionInfo.ContainsKey("BIT_INDEX"))
                                        {
                                            this.WriteWord((short)observable.ConnectionInfo["ADDRESS_NO", 0, 16], observable.ConnectionInfo["BIT_INDEX", 0], observable.ConnectionInfo["BIT_LENGTH", 0], (enumDeviceType)Enum.Parse(typeof(enumDeviceType), observable.ConnectionInfo["DEVICE_TYPE", "W"]), (short)value);
                                        }
                                        else
                                        {
                                            //从ConnectionInfo中查找ADDRESS_NO是否有值，有则返回键ADDRESS_NO对应的值转换成16进制。否则返回0
                                            this.WriteWord((short)observable.ConnectionInfo["ADDRESS_NO", 0, 16], observable.ConnectionInfo["BIT_LENGTH", 0], (enumDeviceType)Enum.Parse(typeof(enumDeviceType), observable.ConnectionInfo["DEVICE_TYPE", "W"]), (short)value);
                                        }
                                    }
                                    break;
                                }
                            case 6:
                                {
                                    short num = Convert.ToInt16(observable.ConnectionInfo["STATION_NO", -1]);
                                    if (num >= 0)
                                    {
                                        this.WriteWordA((short)observable.ConnectionInfo["ADDRESS_NO", 0, 16], num, (enumDeviceType)Enum.Parse(typeof(enumDeviceType), observable.ConnectionInfo["DEVICE_TYPE", "W"]), (short)observable.ConnectionInfo["LENGTH", 0], (string)value);
                                    }
                                    else
                                    {
                                        string[] array = observable.ConnectionInfoString.Split(new char[]
								{
									'='
								});
                                        string text = array[1].Substring(0, 1);
                                        this.WriteWordA((short)observable.ConnectionInfo["ADDRESS_NO", 0, 16], (enumDeviceType)Enum.Parse(typeof(enumDeviceType), observable.ConnectionInfo["DEVICE_TYPE", "W"]), (short)observable.ConnectionInfo["LENGTH", 0], (string)value);
                                    }
                                    break;
                                }
                            case 7:
                                {
                                    short num = Convert.ToInt16(observable.ConnectionInfo["STATION_NO", -1]);
                                    short num2 = (short)observable.ConnectionInfo["ADDRESS_NO", 0, 16];
                                    if (num >= 0)
                                    {
                                        short num3 = 0;
                                        while ((int)num3 < observable.ListSize)
                                        {
                                            this.WriteWord((short)(num2 + num3), observable.ConnectionInfo["BIT_LENGTH", 0], num, (enumDeviceType)Enum.Parse(typeof(enumDeviceType), observable.ConnectionInfo["DEVICE_TYPE", "W"]), ((List<short>)value)[(int)num3]);
                                            num3 += 1;
                                        }
                                    }
                                    break;
                                }
                            case 11:
                                {
                                    enumDeviceType deviceType = (enumDeviceType)Enum.Parse(typeof(enumDeviceType), observable.ConnectionInfo["DEVICE_TYPE", "B"]);
                                    short num = Convert.ToInt16(observable.ConnectionInfo["STATION_NO", -1]);
                                    short num4 = (short)observable.ConnectionInfo["ADDRESS_NO", 0, 16];
                                    short num5 = (short)observable.ConnectionInfo["BIT_INDEX", 0];
                                    List<bool> list = (List<bool>)value;
                                    for (int i = 0; i < observable.ListSize; i++)
                                    {
                                        if (num >= 0)
                                        {
                                            if (CMelsecNetMemory.GetMemoryType(deviceType) == enumMemoryType.Bit)
                                            {
                                                this.WriteBit((short)((int)num4 + i), 0, num, deviceType, list[i]);
                                            }
                                            else
                                            {
                                                this.WriteBit((short)((int)num4 + (i + (int)num5) / 16), (int)((short)((i + (int)num5) % 16)), num, deviceType, list[i]);
                                            }
                                        }
                                        else
                                        {
                                            if (CMelsecNetMemory.GetMemoryType(deviceType) == enumMemoryType.Bit)
                                            {
                                                this.WriteBit((short)((int)num4 + i), 0, deviceType, list[i]);
                                            }
                                            else
                                            {
                                                this.WriteBit((short)((int)num4 + (i + (int)num5) / 16), (int)((short)((i + (int)num5) % 16)), deviceType, list[i]);
                                            }
                                        }
                                    }
                                    break;
                                }
                        }
                        result = 0;
                    }
                }
            }
            return result;
        }
        /// <summary>
        /// 执行所有的PLC读取操作，包括读Bit，读Word.
        /// </summary>
        /// <param name="observable"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public override int Read(Observable observable, out object value)
        {
            value = null;
            int result;
            if (!base.Connected)
            {
                result = 1;
            }
            else
            {
                if (observable.ConnectionInfoString == string.Empty)
                {
                    result = 1;
                }
                else
                {
                    if (base.ConnectionState == FBConnectionState.DISCONNECTED)
                    {
                        result = 1;
                    }
                    else
                    {
                        /*                        lock (this.m_Monitor)
                                                {

                                                }*/
                        try
                        {
                            switch (observable.DataType.Value())
                            {
                                case 0:
                                    {
                                        bool flag2;
                                        if (!this.m_MonitorMemory[observable.ConnectionInfo["DEVICE_TYPE", "B"]].ReadBit((short)observable.ConnectionInfo["ADDRESS_NO", 0, 16], (short)observable.ConnectionInfo["BIT_INDEX", 0], out flag2))
                                        {
                                        }
                                        value = flag2;
                                        break;
                                    }
                                case 2:
                                    {
                                        short num;
                                        if (observable.ConnectionInfo.ContainsKey("BIT_INDEX"))
                                        {
                                            if (!this.m_MonitorMemory[observable.ConnectionInfo["DEVICE_TYPE", "B"]].ReadWord((short)observable.ConnectionInfo["ADDRESS_NO", 0, 16], observable.ConnectionInfo["BIT_INDEX", 0], observable.ConnectionInfo["BIT_LENGTH", 0], out num))
                                            {
                                            }
                                        }
                                        else
                                        {
                                            if (!this.m_MonitorMemory[observable.ConnectionInfo["DEVICE_TYPE", "B"]].ReadWord((short)observable.ConnectionInfo["ADDRESS_NO", 0, 16], observable.ConnectionInfo["BIT_LENGTH", 0], out num))
                                            {
                                            }
                                        }
                                        value = num;
                                        break;
                                    }
                                case 6:
                                    {
                                        short num2 = Convert.ToInt16(observable.ConnectionInfo["STATION_NO", -1]);
                                        string text = "";
                                        //if (num2 >= 0)
                                        //{
                                        //    if (!this.ReadWordA((short)observable.ConnectionInfo["ADDRESS_NO", 0, 16], num2, (enumDeviceType)Enum.Parse(typeof(enumDeviceType), observable.ConnectionInfo["DEVICE_TYPE", "W"]), (short)observable.ConnectionInfo["LENGTH", 0], out text))
                                        //    {
                                        //    }
                                        //}
                                        //else
                                        //{
                                        //    if (!this.ReadWordA((short)observable.ConnectionInfo["ADDRESS_NO", 0, 16], (enumDeviceType)Enum.Parse(typeof(enumDeviceType), observable.ConnectionInfo["DEVICE_TYPE", "W"]), (short)observable.ConnectionInfo["LENGTH", 0], out text))
                                        //    {
                                        //    }
                                        //}
                                        if (this.m_MonitorMemory[observable.ConnectionInfo["DEVICE_TYPE", "W"]].ReadWordA((short)observable.ConnectionInfo["ADDRESS_NO", 0, 16], (short)observable.ConnectionInfo["LENGTH", 0], out text))
                                        {

                                        }
                                        value = text;
                                        break;
                                    }
                                case 7:
                                    {
                                        List<short> list = new List<short>(observable.ListSize);
                                        short num = 0;
                                        short num3 = 0;
                                        while ((int)num3 < observable.ListSize)
                                        {
                                            if (!this.m_MonitorMemory[observable.ConnectionInfo["DEVICE_TYPE", "W"]].ReadWord((short)(observable.ConnectionInfo["ADDRESS_NO", 0, 16] + (int)num3), 1, out num))
                                            {
                                            }
                                            list.Add(num);
                                            num3 += 1;
                                        }
                                        value = list;
                                        break;
                                    }
                                case 11:
                                    {
                                        List<bool> list2 = new List<bool>(observable.ListSize);
                                        CMelsecNetMemory cMelsecNetMemory = this.m_MonitorMemory[observable.ConnectionInfo["DEVICE_TYPE", "B"]];
                                        short num4 = (short)observable.ConnectionInfo["ADDRESS_NO", 0, 16];
                                        short num5 = (short)observable.ConnectionInfo["BIT_INDEX", 0];
                                        bool flag2 = false;
                                        for (int i = 0; i < observable.ListSize; i++)
                                        {
                                            if (cMelsecNetMemory.MemoryType == enumMemoryType.Bit)
                                            {
                                                cMelsecNetMemory.ReadBit((short)((int)num4 + i), 0, out flag2);
                                            }
                                            else
                                            {
                                                cMelsecNetMemory.ReadBit((short)((int)num4 + (i + (int)num5) / 16), (short)((i + (int)num5) % 16), out flag2);
                                            }
                                            list2.Add(flag2);
                                        }
                                        value = list2;
                                        break;
                                    }
                            }
                        }
                        catch (Exception ex)
                        {
                            LogHelper.loggerError("在read方法中,执行所有的PLC读取操作异常", ex);
                        }
                        result = 0;

                    }
                }
            }
            return result;
        }
        //2023.04.12 By.Jiang - PlayBack Log 
        public override void UpdatePlaybackRawMemory(string plcData)
        {
            if (!m_PlaybackMode)
            {
                return;
            }
            try
            {
                string[] strArray = plcData.Split(new char[] { '@' }, StringSplitOptions.RemoveEmptyEntries);
                int index = 0;

                foreach (CMelsecNetMemory current in this.m_MonitorMemory.Values)
                {
                    byte[] byteArray = Helper.ToBytesFromHexString(strArray[index]);  //将PLC String => Byte[]
                    short[] shortArray = new short[byteArray.Length / 2];
                    for (int i = 0, j = 0; i < current.RawMemory.Length; i++, j += 2)
                    {
                        shortArray[i] = (short)((short)(byteArray[j + 1] << 8) + byteArray[j]);
                        current.RawMemory[i] = shortArray[i];
                    }
                    index++;
                }

            }
            catch (Exception ex)
            {

            }
        }
    }
}
